package com.syni.mdd.sjb.common.component.utils.common.utils;

import com.syni.mdd.sjb.common.component.utils.common.annotations.CheckParams;
import com.syni.mdd.sjb.common.component.utils.common.annotations.CustomQuartz;
import com.syni.mdd.sjb.common.component.utils.common.entity.bo.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ScheduledFuture;

@RestController
@RequestMapping("/task")
public class TimedTasksUtils implements ApplicationListener<ContextRefreshedEvent> {
    private static final Map<String, Task> cronTaskMap = new HashMap<>();

    private static final Map<String, ScheduledFuture> scheduledFuture = new HashMap<>();

    @Autowired(required = false)
    ThreadPoolTaskScheduler threadPoolTaskScheduler;

    @Override
    public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
        Map<String,Object> beansWithAnnotation = contextRefreshedEvent.getApplicationContext().getBeansWithAnnotation(CustomQuartz.class);
        if(beansWithAnnotation != null && beansWithAnnotation.size() > 0){
            for(Map.Entry<String,Object> entry : beansWithAnnotation.entrySet()) {
                Runnable origin = (Runnable) AopTargetUtils.getTarget(entry.getValue());
                if (origin == null) {
                    return;
                }
                CustomQuartz customQuartz = origin.getClass().getAnnotation(CustomQuartz.class);
                cronTaskMap.put("orderRefund",new Task(customQuartz.cronId(),customQuartz.cron(),origin));
            }
            if(cronTaskMap.size() > 0){
                cronTaskMap.forEach((key,value) ->{
                    scheduledFuture.put(value.getCronId(),threadPoolTaskScheduler.schedule(value.getRunnable(), new CronTrigger(value.getCron())));
                });
            }
        }
    }

    /*@PostConstruct
    public void init(){
        //cronTaskMap.put("orderRefund",new Task("orderRefund","0/1 * * * * ?",new OrderRefundJob()));


        if(cronTaskMap.size() > 0){
            cronTaskMap.forEach((key,value) ->{
                scheduledFuture.put(value.getCronId(),threadPoolTaskScheduler.schedule(value.getRunnable(), new CronTrigger(value.getCron())));
            });
        }
    }*/

    @PostMapping("/updateTaskCron")
    @CheckParams(checkAuth = true)
    public Map<String,Object> updateTaskCron(@RequestBody ParamsMap paramsMap){
        String cronId = paramsMap.getString("cronId");
        String cron = paramsMap.getString("cron");
        if(scheduledFuture.containsKey(cronId)){
            ScheduledFuture future = scheduledFuture.get(cronId);
            if (future != null) {
                future.cancel(false);
            }
        }
        if(cronTaskMap.containsKey(cronId)) {
            scheduledFuture.put(cronId, threadPoolTaskScheduler.schedule(cronTaskMap.get(cronId).getRunnable(), new CronTrigger(cron)));
        }
        return ResultMapHelper.success();
    }


}
